package com.ashafa.server;

import java.io.IOException;
import java.io.Writer;
import java.io.PrintWriter;
import java.io.StringWriter;

import org.mortbay.jetty.handler.ErrorHandler;
import org.mortbay.jetty.HttpGenerator;
import org.mortbay.util.StringUtil;
import javax.servlet.http.HttpServletRequest;



public class CustomErrorHandler extends ErrorHandler{

	boolean isWebApp;

	public CustomErrorHandler(boolean isWebApp, boolean showStacks){
		this.isWebApp =  isWebApp;
		this.setShowStacks(showStacks);
	}
	

	protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
	throws IOException
	{
	    
		if(message == null){
			message = HttpGenerator.getReason(code);
		} else {
	        message= StringUtil.replace(message, "&", "&amp;");
	        message= StringUtil.replace(message, "<", "&lt;");
	        message= StringUtil.replace(message, ">", "&gt;");
	    }
		
		writer.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html>\n<head>\n");
		writeCustomErrorTitle(writer, code);
		writeCustomErrorCss(writer);
		writer.write("</head>\n<body>\n\n");
		writeCustomErrorHeader(writer, code);
		writeCustomErrorMessage(writer, code, message, request);
		if(showStacks){
			writeCustomErrorPageStacks(request, writer);
		}
		writer.write("\n</body>\n</html>\n");
	}
	
	void writeCustomErrorTitle(Writer writer, int code) throws IOException{
		writer.write("<title>");
		if(code == 404){
			if(isWebApp){
				writer.write("Routing Exception");
			} else {
				writer.write("404 Error");
			}
		} else {
			writer.write(code + " Application Exception");
		}
		writer.write("</title>\n");
	}
	
	void writeCustomErrorCss(Writer writer) throws IOException{
		
		writer.write("<style type=\"text/css\"> \n" + 
		    "body { background-color: #fff; color: #333; } \n\n" + 
		    "body, p, ol, ul, td { \n" + 
		    "  font-family: verdana, arial, helvetica, sans-serif; \n" + 
		    "  font-size:   13px; \n" + 
		    "  line-height: 18px; \n" + 
		    "}\n\n" + 
		    "pre { \n" + 
		    "  background-color: #eee; \n" + 
		    "  padding: 10px; \n" + 
		    "  font-size: 11px; \n" + 
		    "}\n\n" + 
		    "pre.stack { \n" + 
		    "  background-color: #ffffcc; \n" +
		    "}\n\n" + 
		    "a { color: #000; } \n" + 
		    "a:visited { color: #666; } \n" + 
		    "a:hover { color: #fff; background-color:#000; } \n" + 
		  	"</style>");
		
	}
	
	void writeCustomErrorHeader(Writer writer, int code) throws IOException{
		
		writer.write("<h1>");
		if(code == 404){
			if(isWebApp){
				writer.write("Routing Exception");
			} else {
				writer.write("404 Error");
			}
		} else {
			writer.write(code + " Application Exception");
		}
		writer.write("</h1>\n");
		
	}
	
	void writeCustomErrorMessage(Writer writer, int code, String message, HttpServletRequest request) throws IOException{
		
		writer.write("<p><pre>");
		if(code == 404){
			String uri = request.getRequestURI();
	        if (uri != null)
	        {
	            uri = StringUtil.replace(uri, "&", "&amp;");
	            uri = StringUtil.replace(uri, "<", "&lt;");
	            uri = StringUtil.replace(uri, ">", "&gt;");
	        }
	        if(isWebApp){
	        	writer.write("no route to a template found to match \""+ uri + "\" in urls.json.");
	        } else {
	        	writer.write("\""+ uri + "\" not found.");
	        }
		} else {
			writer.write(message);
		}
		writer.write("</pre></p>\n");
		
	}
	
	void writeCustomErrorPageStacks(HttpServletRequest request, Writer writer) throws IOException{
		Throwable th = (Throwable)request.getAttribute("javax.servlet.error.exception");
        while(th!=null)
        {
            writer.write("<h3>Stack trace:</h3>\n<p><pre class=\"stack\">");
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            th.printStackTrace(pw);
            pw.flush();
            writer.write(sw.getBuffer().toString());
            writer.write("</pre></p>\n");

            th =th.getCause();
        }
	}

}
